package model

import (
	"errors"
	"fmt"
	"github.com/jinzhu/gorm"
	"yunwei/go_api/application/constants"
	"yunwei/go_api/application/database"
	"yunwei/go_api/application/utils"
)

type HostCategory struct {
	gorm.Model
	Name string `json:"name" gorm:"type:varchar(255);unique_index"`
}

type HostCategoryInstance struct {
	ID   uint   `json:"id"`
	Name string `json:"name"`
}

// 批量执行命令
type CmdParam struct {
	Cmd     string `json:"cmd"`
	HostIds []int  `json:"host_ids"`
}

// 设置表名
func (category HostCategory) TableName() string {
	return "host_category"
}

// 添加主机类别
func (category *HostCategory) Insert() error {
	err := database.Orm.Create(&category).Error
	return err
}

// 获取主机分类列表
func (category *HostCategory) GetAll() ([]HostCategoryInstance, error) {
	var categories []HostCategoryInstance
	err := database.Orm.Table(category.TableName()).Order(" id DESC ").Select("id, name").Scan(&categories).Error
	return categories, err
}

// 根据指定ID获取主机类别
func (category *HostCategory) GetOneById(id uint) error {
	var hh HostCategory
	database.Orm.Where("id = ?", id).First(&hh)
	err := database.Orm.First(&category, id).Error
	return err
}

/**
主机信息模型
*/

type Host struct {
	gorm.Model
	Name           string       `json:"name" gorm:"type:varchar(255)"`
	IpAddr         string       `json:"ip_addr" gorm:"type:varchar(255)"`
	Port           uint         `json:"port" gorm:"type:int"`
	Username       string       `json:"username" gorm:"varchar(255)"`
	Password       string       `json:"password,omitempty" gorm:"varchar(255)"`
	Remark         string       `json:"remark,omitempty" gorm:"varchar(255)"`
	HostCategoryID uint         `json:"host_category_id"`
	HostCategory   HostCategory `json:"host_category"  gorm:"foreignKey:HostCategoryID;references:ID"`

	PrivateKey string `json:"private_key,omitempty" gorm:"type:text"`
	PublicKey  string `json:"public_key,omitempty" gorm:"type:text"`
}

type HostInstance struct {
	ID           uint   `json:"id"`
	Name         string `json:"name"`
	IpAddr       string `json:"ip_addr"`
	Port         uint   `json:"port"`
	Username     string `json:"username"`
	CategoryID   uint   `json:"host_category_id"`
	CategoryName string `json:"category_name"`
	Remark       string `json:"remark"`
}

/**
设置表名
*/

func (host Host) TableName() string {
	return "host_info"
}

/**
添加主机
*/

func (host *Host) Insert() error {
	err := database.Orm.Create(&host).Error
	return err
}

/**
获取所有主机列表
*/

func (host Host) GetAll(name string, hostCategoryId uint, IpAddr string) ([]Host, error) {
	var hosts []Host
	query := database.Orm.Table(host.TableName())
	if name != "" {
		query = query.Where(" name LIKE ? ", "%"+name+"%")
	}
	if hostCategoryId > 0 {
		query = query.Where(" host_category_id = ? ", hostCategoryId)
	}
	if IpAddr != "" {
		query = query.Where(" ip_addr LIKE ? ", "%"+IpAddr+"%")
	}

	err := query.Order(" id DESC ").Preload("HostCategory").Find(&hosts).Error
	return hosts, err
}

/**
根据指定ID获取主机
*/

func (host *Host) GetOneById(id uint) error {
	err := database.Orm.First(&host, id).Error
	return err
}

/**
删除主机
*/

func (host *Host) Delete() (err error) {
	err = database.Orm.Delete(&host).Error
	return err
}

/*
*
执行终端命令
*/
func ExecuteCMD(id int, cmd string) (string, error) {
	host := Host{}
	err := host.GetOneById(uint(id))
	if err != nil {
		return "", err
	}
	cli := utils.NewSSH(host.IpAddr, host.Username, "", host.PrivateKey, "key", int(host.Port))
	if err := cli.Connect(); err != nil {
		return "", errors.New(constants.HostInfoEror)
	}
	defer func(cli *utils.SSH) {
		_ = cli.Client.Close()
		_ = cli.Session.Close()
	}(cli)

	output, err := cli.Run(cmd)
	if err != nil {
		fmt.Println(err)
	}
	return output, err
}

/**
批量主机执行指令
*/

func ExecuteCMDList(HostIds []int, Cmd string) error {
	for _, id := range HostIds {
		fmt.Println(id)
		_, err := ExecuteCMD(id, Cmd)
		if err != nil {
			return err
		}
	}
	return nil
}
